/**
 * DSM - Distributed Search Manager
 * Developed by Milspec Research International Pty Ltd
 * $Author: gsingh $
 * $Revision: 1.1 $
 * $Date: 2006/06/09 06:38:19 $
 * (c)Copyright 2004
 * education.au limited
 * DEST
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * Neither the names education.au limited, DEST nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 * To the extent permitted by law, the copyright owners of this software and
 * its contributors:
 * (i) exclude all warranties in relation to the software; and
 * (ii) exclude liability for all losses, costs, expenses and damages arising
 * in any way from the use of the software whether arising from or in
 * relation to breach of contract, negligence or any other tort, in equity
 * or otherwise. If the software is in breach of a warranty which is
 * implied by law, the copyright owners and contributors liability is
 * limited to the replacement of the software.
 *
 * @author	gsingh
 */

package au.edu.educationau.opensource.dsm.adapters;

import java.io.StringReader;
import java.net.URL;
import java.util.ArrayList;

import au.edu.educationau.opensource.dsm.DeusExMachina;
import au.edu.educationau.opensource.dsm.adapters.contenthandler.LOMXMLContentHandler;
import au.edu.educationau.opensource.dsm.obj.SearchCriteria;
import au.edu.educationau.opensource.dsm.worker.ResultSetUnifier;

/**
 * Adapter for the VSQI Implementation by Cenorm
 */

public class SqiSearchAdapterImpl extends SearchAdapter {
	private static final String SQI_QUERY_XML = "<simpleQuery>QUERYXML</simpleQuery>";
	private String uniqueIdentifier = "";
	private String targetSessionID = null;

	/** Parent constructor */
	public SqiSearchAdapterImpl() {
		super();
	}

	/**
	 * See the SearchAdapter abstract method doPrime
	 * 
	 * @exception Throwable
	 */
	public void doPrime() throws Throwable {
		StringBuffer identifier = new StringBuffer();
		identifier.append(super.getSearchCriteria().getQuery()).append(":").append(super.getSearchCriteria().getKeywordConstraint());
		uniqueIdentifier = identifier.toString();
	}

	/**
	 * See the SearchAdapter abstract method doPerform
	 * 
	 * @exception Throwable
	 */
	public ArrayList doPerform() throws Throwable {
		ArrayList batch = new ArrayList();
		SearchCriteria criteria = super.getSearchCriteria();
		String resultData = "";

		if (DeusExMachina._SOAPSearchResultCacheService().hasResults(super.getProperties().getAdapterCode(), uniqueIdentifier)) {
			resultData = (String) DeusExMachina._SOAPSearchResultCacheService().getResults(super.getProperties().getAdapterCode(), uniqueIdentifier);
		} else {
			be.cenorm.www.TargetServiceBinding searchLocator = new be.cenorm.www.TargetServiceBindingLocator();
			be.cenorm.www.SqiTargetBindingStub searchStub = (be.cenorm.www.SqiTargetBindingStub) searchLocator.getTargetServiceBinding(new URL(super.getProperties().getExtraProperty("target.url")));

			String constraint = criteria.getKeywordConstraint();
			String[] queryKeywords = criteria.getQueryArray();
			StringBuffer queryXML = new StringBuffer();
			StringBuffer subQueryXML = new StringBuffer();

			for (int i = 0; i < queryKeywords.length; i++) {
				subQueryXML.append("<term>");
				subQueryXML.append(queryKeywords[i]);
				subQueryXML.append("</term>");
			}

			queryXML.append(SQI_QUERY_XML.replaceAll("QUERYXML", subQueryXML.toString()));

			String targetSessionID = super.getProperties().getExtraProperty("session.identifier");

			if (targetSessionID == null || targetSessionID.length() <= 0) {
				/**
				 * <pre>
				 * If a session.identifier is NOT present we assume its an anonymous session
				 * </pre>
				 */
				be.cenorm.www.SessionManagementServiceBinding sessionLocator = new be.cenorm.www.SessionManagementServiceBindingLocator();
				be.cenorm.www.SqiSessionManagementBindingStub sessionStub = (be.cenorm.www.SqiSessionManagementBindingStub) sessionLocator.getSessionManagementServiceBinding(new URL(super.getProperties().getExtraProperty("session.url")));
				targetSessionID = sessionStub.createAnonymousSession();
				searchStub.setQueryLanguage(targetSessionID, "vsqi");
				searchStub.setResultsFormat(targetSessionID, "lom");
				searchStub.setResultsSetSize(targetSessionID, super.getProperties().getBatchSize());
				resultData = searchStub.synchronousQuery(targetSessionID, queryXML.toString(), 1);
				sessionStub.destroySession(targetSessionID);
			} else {
				resultData = searchStub.synchronousQuery(targetSessionID, queryXML.toString(), 1);
			}

			if (null != resultData) {
				DeusExMachina._SOAPSearchResultCacheService().addResults(super.getProperties().getAdapterCode(), uniqueIdentifier, resultData);
			}
		}

		if (null != resultData && resultData.length() > 0) {
			// Process the results here
			LOMXMLContentHandler contentHandler = new LOMXMLContentHandler();
			contentHandler.setSearchAdapterProperties(super.getProperties());
			contentHandler.setSearchCriteria(criteria);
			contentHandler = (LOMXMLContentHandler) ResultSetUnifier.processXML(new StringReader(resultData), contentHandler);
			batch = contentHandler.getResults();
		}

		return batch;
	}

	/**
	 * See the SearchAdapter abstract method doNextBatch
	 * 
	 * @exception Throwable
	 */
	public boolean doNextBatch() throws Throwable {
		return false;
	}

	/**
	 * See the SearchAdapter abstract method doStopNice
	 * 
	 * @exception Throwable
	 */
	public void doStopNice() throws Throwable {
		// does nothing here
	}

	/**
	 * See the SearchAdapter abstract method doStopForce
	 * 
	 */
	public void doStopForce() throws Throwable {
		// does nothing here
	}

	/** Class name display */
	public String toString() {
		return "o.m.d.a.SqiSearchAdapterImpl";
	}
} // -- EOF
